#include "ScriptEngine.h"
#include "EnermyObj.h"
#include "BossObj.h"
#include <boost/ref.hpp>

lua_State* ScriptEngine::L = NULL;

void ScriptEngine::Init()
{
	L = luaL_newstate();
	lua_cpcall(L, luaopen_base, 0);
	lua_cpcall(L, luaopen_io, 0);
	lua_cpcall(L, luaopen_string, 0);
	lua_cpcall(L, luaopen_table, 0);
	lua_cpcall(L, luaopen_math, 0);
	lua_cpcall(L, luaopen_debug, 0); 
	lua_cpcall(L, luaopen_os, 0);
	luabind::open(L);
	Bind_All(L);
	luaL_dofile(L,"Script/EngineInit.lua");
}

void ScriptEngine::Release()
{
	lua_close(L);
}
namespace VV {
	void setEnermy(EnermyInfo* ei,const std::string str){ei->enermy = str;}
	void setBullet(EnermyInfo* ei,const std::string str){ei->bullet = str;}
	void setControl(EnermyInfo* ei,const std::string str){ei->control = str;}
	void setX(EnermyInfo* ei,float f){ei->x = f;}
	void setY(EnermyInfo* ei,float f){ei->y = f;}
	void setHP(EnermyInfo* ei,int i){ei->hp = i;}
	void setTIME(EnermyInfo* ei,float t){ei->time = t;}
	void setbulletType(EnermyInfo* ei,int i){ei->bulletType = i;}
}

void ScriptEngine::Bind_All( lua_State *L )
{
	using namespace luabind;
	module(L)
		[
			class_<GameObj>("GameObj"),
			class_<EnermyObj,GameObj>("EnermyObj")
			.def(constructor<hgeAnimation*,hgeSprite*,float,float,float,int,std::string,int>())
			.def("MoveTo",&EnermyObj::MoveTo)
			.def("getX",&EnermyObj::getX)
			.def("getY",&EnermyObj::getY)
			.def("Fire",&EnermyObj::Fire)
			.def("getLastFireTime",&EnermyObj::getLastFireTime),

			class_<BossObj,EnermyObj>("BossObj")
			.def(constructor<hgeAnimation*,float,float,float,int,std::string,hgeSprite*,hgeSprite*,hgeSprite*>())
			.def("fire",&BossObj::fire)
			.def("getHP",&BossObj::getHP)
			.def("clearBullet",&BossObj::clearBullet),

			class_<BulletInfo,GameObj>("BulletInfo")
			.def(constructor<hgeSprite*,float,float,float,float,float,float,int>())
			.def_readwrite("X",&BulletInfo::m_x)
			.def_readwrite("Y",&BulletInfo::m_y)
			.def_readwrite("par",&BulletInfo::par)
			.def_readonly("sX",&BulletInfo::sx)
			.def_readonly("sY",&BulletInfo::sy)
			.def_readonly("sTime",&BulletInfo::stime),

			class_<EnermyInfo>("EnermyInfo")
			.def(constructor<>())
			.def("setEnermy",&VV::setEnermy)
			.def("setBullet",&VV::setBullet)
			.def("setControl",&VV::setControl)
			.def("setX",&VV::setX)
			.def("setY",&VV::setY)
			.def("setHP",&VV::setHP)
			.def("setTIME",&VV::setTIME)
			.def("setbulletType",&VV::setbulletType),

			class_<BossInfo>("BossInfo")
			.def(constructor<>())
			.def_readwrite("BossName",&BossInfo::BossName)
			.def_readwrite("Bullet1",&BossInfo::Bullet1)
			.def_readwrite("Bullet2",&BossInfo::Bullet2)
			.def_readwrite("Bullet3",&BossInfo::Bullet3)
			.def_readwrite("X",&BossInfo::x)
			.def_readwrite("Y",&BossInfo::y)
			.def_readwrite("time",&BossInfo::time)
			.def_readwrite("HP",&BossInfo::hp)
			.def_readwrite("control",&BossInfo::control)

		];
}

EnermyInfo ScriptEngine::Controller( const char* filename,float time)
{
	return luabind::call_function<EnermyInfo>(L,"Controller",time);
}

bool ScriptEngine::Compute(const char* funcname,float stime,float ntime,EnermyObj *obj) {
	return luabind::call_function<bool>(L,funcname,stime,ntime,obj);
}

bool ScriptEngine::Compute(const char* funcname,float stime,float ntime,BossObj *obj) {
	return luabind::call_function<bool>(L,funcname,stime,ntime,obj);
}

void ScriptEngine::CallBulletFunc( const char* funcname,BulletInfo *obj,float playerX,float playerY,float ntime )
{
	luabind::call_function<void>(L,funcname,obj,playerX,playerY,ntime);
}

BossInfo ScriptEngine::BossController( float time )
{
	return luabind::call_function<BossInfo>(L,"BossController",time);
}